<template>
  <div class="app-container">
    <el-form
      :model="queryParams"
      ref="queryRef"
      :inline="true"
      v-show="showSearch"
      label-width="80px"
    >
      <el-form-item label="场景名称" prop="name">
        <el-input
          v-model="queryParams.name"
          placeholder="请输入场景名称"
          clearable
          @keyup.enter="handleQuery"
        />
      </el-form-item>
      <el-form-item label="场景描述" prop="remark">
        <el-input
          v-model="queryParams.remark"
          placeholder="请输入场景描述"
          clearable
          @keyup.enter="handleQuery"
        />
      </el-form-item>
      <!-- <el-form-item label="图标" prop="icon">
        <el-input
          v-model="queryParams.icon"
          placeholder="请输入图标"
          clearable
          @keyup.enter="handleQuery"
        />
      </el-form-item> -->
      <!-- <el-form-item label="排序字段" prop="sortValue">
        <el-input
          v-model="queryParams.sortValue"
          placeholder="请输入排序字段"
          clearable
          @keyup.enter="handleQuery"
        />
      </el-form-item> -->
      <el-form-item>
        <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
        <el-button icon="Refresh" @click="resetQuery">重置</el-button>
      </el-form-item>
    </el-form>

    <el-row :gutter="10" class="mb8">
      <el-col :span="1.5">
        <el-button
          type="primary"
          plain
          icon="Plus"
          @click="handleAdd"
          v-hasPermi="['web:lm:kb:sdkLmScene:add']"
        >
          新增
        </el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="success"
          plain
          icon="Edit"
          :disabled="single"
          @click="handleUpdate({})"
          v-hasPermi="['web:lm:kb:sdkLmScene:edit']"
        >
          修改
        </el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="danger"
          plain
          icon="Delete"
          :disabled="multiple"
          @click="handleDelete({})"
          v-hasPermi="['web:lm:kb:sdkLmScene:remove']"
        >
          删除
        </el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="info"
          plain
          icon="Upload"
          @click="handleImport"
          v-hasPermi="['web:lm:kb:sdkLmScene:import']"
        >
          导入
        </el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="warning"
          plain
          icon="Download"
          @click="handleExport"
          v-hasPermi="['web:lm:kb:sdkLmScene:export']"
        >
          导出
        </el-button>
      </el-col>
      <right-toolbar v-model:showSearch="showSearch" @query-table="getList" />
    </el-row>

    <el-table v-loading="loading" :data="list" @selection-change="handleSelectionChange">
      <el-table-column type="selection" width="55" align="center" />
      <!-- <el-table-column label="主键" align="center" prop="id" /> -->
      <el-table-column label="场景名称" align="center" prop="name" />
      <el-table-column label="场景编码" align="center" prop="code" />

      <el-table-column
        label="向量库状态"
        align="center"
        prop="quantified"
        :formatter="quantifiedFormat"
      />
      <el-table-column label="场景描述" align="center" prop="remark" />

      <el-table-column label="是否启用" align="center" prop="enable">
        <template #default="{ row }">
          <div>
            <el-switch
              v-model="row.enable"
              :active-value="true"
              :inactive-value="false"
              inline-prompt
              style="--el-switch-on-color: #13ce66; --el-switch-off-color: #ff4949"
              active-text="启用"
              inactive-text="停用"
              @change="handleEnableChange(row)"
            />
          </div>
        </template>
      </el-table-column>
      <el-table-column label="图标" align="center" prop="icon">
        <template #default="{ row }">
          <div>
            <img :src="getImageUrl(row.icon)" alt="" />
          </div>
        </template>
      </el-table-column>
      <!-- <el-table-column label="提示词" align="center" prop="prompt" /> -->
      <!-- <el-table-column label="是否删除" align="center" prop="del" /> -->
      <el-table-column label="排序字段" align="center" prop="sortValue" />
      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
        <template #default="scope">
          <!-- <el-button
            link
            type="primary"
            icon="View"
            @click="handleQuantified(scope.row)"
            v-hasPermi="['web:lm:kb:sdkLmScene:edit']"
          >
            向量库
          </el-button> -->
          <el-button
            link
            type="primary"
            icon="Edit"
            @click="handleUpdate(scope.row)"
            v-hasPermi="['web:lm:kb:sdkLmScene:edit']"
          >
            修改
          </el-button>
          <el-button
            link
            type="primary"
            icon="Delete"
            style="color: red"
            @click="handleDelete(scope.row)"
            v-hasPermi="['web:lm:kb:sdkLmScene:remove']"
          >
            删除
          </el-button>
          <!-- <el-button
            link
            type="warning"
            icon="Switch"
            @click="handleSyncQuantified(scope.row)"
            v-hasPermi="['web:lm:kb:sdkLmScene:edit']"
          >
            同步向量库
          </el-button> -->
        </template>
      </el-table-column>
    </el-table>

    <pagination
      v-show="total > 0"
      :total="total"
      v-model:page="pageParams.pageNum"
      v-model:limit="pageParams.pageSize"
      @pagination="getList"
    />

    <el-dialog
      :title="title"
      v-model="open"
      width="1000px"
      append-to-body
      :close-on-press-escape="false"
      :close-on-click-modal="false"
    >
      <el-form ref="formRef" :model="form" :rules="rules" label-width="86px">
        <el-form-item label="场景名称" prop="name">
          <el-input v-model="form.name" placeholder="请输入场景名称" />
        </el-form-item>
        <el-form-item label="场景编码" prop="code">
          <el-input v-model="form.code" placeholder="请输入场景编码" @blur="handleValidCode" />
        </el-form-item>
        <el-form-item label="场景描述" prop="remark">
          <el-input
            type="textarea"
            show-word-limit
            maxlength="200"
            v-model="form.remark"
            placeholder="请输入场景描述"
          />
        </el-form-item>
        <el-form-item label="是否启用" prop="enable">
          <el-switch
            v-model="form.enable"
            :active-value="true"
            :inactive-value="false"
            style="--el-switch-on-color: #13ce66; --el-switch-off-color: #ff4949"
            active-text="启用"
            inactive-text="停用"
          />
        </el-form-item>
        <el-form-item label="图标" prop="icon">
          <ImageUpload
            v-model="form.icon"
            :limit="1"
            :isShowTip="false"
            :fileType="['png', 'jpg', 'jpeg']"
            @success="handleSetFileInfo"
          />
        </el-form-item>
        <el-form-item label="提示词" prop="prompt">
          <el-input
            v-model="form.prompt"
            type="textarea"
            show-word-limit
            :rows="5"
            maxlength="2000"
            placeholder="请输入内容"
          />
        </el-form-item>
        <el-form-item label="关联知识库" prop="sdkLmSceneKbList">
          <div class="flex flex-col gap-3 w-full mb-2">
            <div
              v-for="(item, index) in form.sdkLmSceneKbList"
              :key="index"
              class="flex items-center"
            >
              <el-tag>{{ item.kbName }}</el-tag>
              <el-button
                link
                :disabled="!index"
                style="color: #e6a23c; font-size: 20px"
                icon="Top"
                @click="handleKbSort(item, index, 'top')"
              />
              <el-button
                link
                style="margin-left: 0; color: #e6a23c; font-size: 20px"
                icon="Bottom"
                :disabled="index === form.sdkLmSceneKbList.length - 1"
                @click="handleKbSort(item, index, 'bottom')"
              />

              <el-icon color="red" size="18" class="cursor-pointer" @click="handleDeleteKb(item)">
                <Delete />
              </el-icon>
            </div>
          </div>
          <el-button link icon="Plus" style="color: #409eff" @click="handleAddClick">
            添加关联
          </el-button>
        </el-form-item>
        <el-form-item label="排序字段" prop="sortValue">
          <el-input-number
            style="width: 300px"
            v-model="form.sortValue"
            placeholder="请输入排序字段"
          />
        </el-form-item>
        <el-form-item label="主题颜色" prop="color">
          <el-input
            style="width: 300px"
            type="color"
            v-model="form.color"
            @change="changeColor"
            placeholder="请选择主题颜色"
          />
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="submitForm">确 定</el-button>
          <el-button @click="cancel">取 消</el-button>
        </div>
      </template>
    </el-dialog>

    <el-dialog
      :title="upload.title"
      v-model="upload.open"
      width="400px"
      append-to-body
      :close-on-press-escape="false"
      :close-on-click-modal="false"
    >
      <el-upload
        ref="uploadRef"
        :limit="1"
        accept=".xlsx, .xls"
        :headers="upload.headers"
        :action="upload.url + '?updateSupport=' + upload.updateSupport"
        :disabled="upload.isUploading"
        :on-progress="handleFileUploadProgress"
        :on-success="handleFileSuccess"
        :auto-upload="false"
        drag
      >
        <el-icon class="el-icon--upload">
          <upload-filled />
        </el-icon>
        <div class="el-upload__text">将文件拖到此处，或<em>点击上传</em></div>
        <template #tip>
          <div class="el-upload__tip text-center">
            <div class="el-upload__tip">
              <el-checkbox v-model="upload.updateSupport" />
              是否更新已经存在的场景数据
            </div>
            <span>仅允许导入xls、xlsx格式文件。</span>
            <el-link
              type="primary"
              :underline="false"
              style="font-size: 12px; vertical-align: baseline"
              @click="importTemplate"
              >下载模板
            </el-link>
          </div>
        </template>
      </el-upload>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="submitFileForm">确 定</el-button>
          <el-button @click="upload.open = false">取 消</el-button>
        </div>
      </template>
    </el-dialog>

    <kbDialog
      v-model="kbdlg.open"
      :title="kbdlg.title"
      :data="kbdlg.data"
      @selected="handleUpdateSelected"
    />

    <el-dialog
      title="向量库列表"
      v-model="quantifiedShow"
      width="1000px"
      append-to-body
      :close-on-press-escape="false"
      :close-on-click-modal="false"
    >
      <el-table v-loading="quantifyLoading" :data="quantifiedList">
        <el-table-column label="场景名称" align="center" prop="name" />
        <el-table-column label="文件md5" align="center" prop="md5" />
        <el-table-column label="文件路径" align="center" prop="filePath" />
        <el-table-column
          label="量化状态"
          align="center"
          prop="quantifySuccess"
          :formatter="quantifiedFormat"
        />
        <el-table-column label="量化失败原因" align="center" prop="failReason" />
        <el-table-column
          label="删除量化状态"
          align="center"
          prop="delQuantifySuccess"
          :formatter="quantifiedFormat"
        />
        <el-table-column label="删除失败原因" align="center" prop="delQuantifyFailReason" />
        <el-table-column label="同步时间" align="center" prop="createTime" />
      </el-table>
    </el-dialog>
  </div>
</template>

<script setup>
  import { ref } from 'vue';
  import {
    pageSdkLmScene,
    getSdkLmSceneInfo,
    addSdkLmScene,
    updateSdkLmScene,
    delSdkLmScene,
    tplSdkLmScene,
    exportSdkLmScene,
    codeExistsSdkLmScene,
    fileQuantifyLog,
    syncQuantify,
  } from '@/api/intelligencebase/sdkLmScene';
  import { getToken } from '@/utils/auth';
  import modal from '@/plugins/modal';
  import kbDialog from './kbDialog.vue';

  const pageParams = ref({
    pageNum: 1,
    pageSize: 10,
  });
  const queryParams = ref({
    name: null,
    remark: null,
    enable: null,
    icon: null,
    prompt: null,
    del: null,
    sortValue: null,
  });
  const queryRef = ref(null);
  const list = ref([]);
  const open = ref(false);
  const loading = ref(false);
  const showSearch = ref(true);
  const ids = ref([]);
  const single = ref(true);
  const multiple = ref(true);
  const total = ref(0);
  const title = ref('');

  const uploadRef = ref(null);
  const upload = ref({
    open: false,
    title: '',
    isUploading: false,
    updateSupport: 0,
    headers: { Authorization: 'Bearer ' + getToken() },
    url: import.meta.env.VITE_APP_BASE_API + '/web/lm/kb/sdkLmScene/import',
  });

  const quantifiedPageParams = ref({ pageNum: 1, pageSize: 10 });
  const quantifiedTotal = ref(0);
  const quantifiedList = ref([]);
  const quantifiedShow = ref(false);
  const quantifyLoading = ref(false);

  const formRef = ref(null);
  const form = ref({});
  const rules = ref({
    name: [
      { required: true, message: '场景名称必填' },
      {
        required: true,
        min: 0,
        max: 64,
        message: '场景名称长度必须介于 0 和 64 之间',
        trigger: 'blur',
      },
    ],
    code: [{ required: true, message: '场景编码必填' }],
    remark: [{ required: true, message: '场景描述必填' }],
    enable: [{ required: true, message: '请选择是否启用' }],
    icon1: [
      {
        min: 0,
        max: 255,
        message: '图标长度必须介于 0 和 255 之间',
        trigger: 'blur',
      },
    ],
    prompt1: [
      {
        min: 0,
        max: 2000,
        message: '提示词长度必须介于 0 和 2000 之间',
        trigger: 'blur',
      },
    ],
  });

  const kbdlg = ref({
    open: false,
    title: '',
    data: [],
  });

  function getList() {
    loading.value = true;
    pageSdkLmScene(pageParams.value, queryParams.value)
      .then((res) => {
        list.value = res?.data?.records ?? [];
        total.value = res?.data?.total ?? 0;
      })
      .finally(() => {
        loading.value = false;
      });
  }

  function cancel() {
    open.value = false;
    reset();
  }

  function changeColor(val) {
    console.log({ val });
  }

  function reset() {
    form.value = {
      id: null,
      name: null,
      code: null,
      remark: null,
      enable: false,
      icon: null,
      prompt: null,
      del: null,
      sortValue: null,
      createBy: null,
      createTime: null,
      updateBy: null,
      updateTime: null,
      sdkLmSceneKbList: [],
      quantified: null,
    };
    formRef.value?.resetFields();
  }

  //
  function quantifiedFormat(row, column) {
    if (column.property === 'quantified') {
      return row[column.property] ? '已创建' : '未创建';
    } else if (column.property === 'quantifySuccess') {
      return row[column.property] ? '成功' : '失败';
    } else if (column.property === 'delQuantifySuccess') {
      return row[column.property] ? '成功' : '失败';
    }
  }

  // 验证code
  async function handleValidCode() {
    if (!form.value.code?.trim()) return;
    const res = await codeExistsSdkLmScene({ code: form.value.code, id: form.value.id });
    if (res?.data) {
      modal.msgError('场景编码冲突，请重新设置编码');
      return;
    }
  }

  // 添加关联知识库 点击 事件
  function handleAddClick() {
    kbdlg.value = {
      open: true,
      title: '知识库列表',
      data: form.value.sdkLmSceneKbList,
    };
  }

  function getImageUrl(url) {
    const baseUrl = import.meta.env.VITE_APP_BASE_API;
    if (!url) return;
    return baseUrl + url + `?accessToken=${getToken()}`;
  }

  function handleSetFileInfo({ res }) {
    form.value.icon = res.fileName;
  }

  // 知识库列表选中后 确定按钮 点击事件
  function handleUpdateSelected(selection) {
    const sItems = selection.map((item) => {
      return {
        sceneId: form.value.id,
        kbId: item.id,
        kbName: item.name,
        sortValue: item.sortValue || 0,
      };
    });

    form.value.sdkLmSceneKbList.push(...sItems);
    form.value.sdkLmSceneKbList.sort((a, b) => a - b);
  }

  // 关联知识库排序
  function handleKbSort(item, index, type) {
    const newSortV = item.sortValue;
    const preItem = form.value.sdkLmSceneKbList[index - 1];
    const nextItem = form.value.sdkLmSceneKbList[index + 1];

    switch (type) {
      case 'top':
        const preSortV = preItem.sortValue;
        form.value.sdkLmSceneKbList[index - 1] = { ...item, sortValue: preSortV };
        form.value.sdkLmSceneKbList[index] = { ...preItem, sortValue: newSortV };

        break;
      case 'bottom':
        const nextSortV = nextItem.sortValue;
        form.value.sdkLmSceneKbList[index] = { ...nextItem, sortValue: newSortV };
        form.value.sdkLmSceneKbList[index + 1] = { ...item, sortValue: nextSortV };
        break;
      default:
        break;
    }
  }

  // 关联知识库 删除 点击事件
  function handleDeleteKb(row) {
    const _ids = row?.kbId;
    modal
      .confirm('是否确认删除关联知识库编号为"' + _ids + '"的数据项？')
      .then(() => {
        form.value.sdkLmSceneKbList = form.value.sdkLmSceneKbList.filter(
          (item) => item.kbId !== row.kbId,
        );
      })
      .catch(() => {});
  }

  function handleEnableChange(row) {
    let text = row.enable === true ? '启用' : '停用';
    modal
      .confirm('确认要"' + text + '""' + row.id + '"数据吗?')
      .then(function () {
        return updateSdkLmScene(row);
      })
      .then(() => {
        modal.msgSuccess(text + '成功');
        getList();
      })
      .catch(function () {
        row.enable = row.enable === true ? false : true;
      });
  }

  function handleQuery() {
    pageParams.value.pageNum = 1;
    getList();
  }

  function resetQuery() {
    queryRef.value?.resetFields();
    handleQuery();
  }

  function handleSelectionChange(selection) {
    ids.value = selection.map((item) => item.id);
    single.value = selection.length !== 1;
    multiple.value = !selection.length;
  }

  function handleAdd() {
    reset();
    title.value = '添加场景';
    open.value = true;
  }

  function handleUpdate(row) {
    reset();
    const _id = row?.id ?? ids.value[0];
    getSdkLmSceneInfo(_id).then((res) => {
      form.value = res.data;
      title.value = '修改场景';
      open.value = true;
    });
  }

  // 向量库
  // eslint-disable-next-line
  async function handleQuantified(row) {
    quantifyLoading.value = true;
    const res = await fileQuantifyLog({ sceneId: row.id }).finally(() => {
      quantifyLoading.value = false;
    });
    if (!res) {
      quantifiedPageParams.value = { pageNum: 1, pageSize: 10 };
      quantifiedTotal.value = 0;
      quantifiedList.value = [];
      return;
    }
    const { records, total } = res.data;
    quantifiedList.value = records.map((item) => ({ ...item, name: row.name }));
    quantifiedTotal.value = total;
    quantifiedShow.value = true;
  }

  function submitForm() {
    formRef.value.validate((valid) => {
      if (valid) {
        if (form.value.id) {
          updateSdkLmScene(form.value).then(() => {
            modal.msgSuccess('修改成功');
            open.value = false;
            getList();
          });
        } else {
          addSdkLmScene(form.value).then(() => {
            modal.msgSuccess('新增成功');
            open.value = false;
            getList();
          });
        }
      }
    });
  }

  function handleDelete(row) {
    const _ids = row?.id ?? ids.value.join(',');
    modal
      .confirm('是否确认删除场景编号为"' + _ids + '"的数据项？')
      .then(() => {
        return delSdkLmScene(_ids);
      })
      .then(() => {
        getList();
        modal.msgSuccess('删除成功');
      })
      .catch(() => {});
  }

  // eslint-disable-next-line
  function handleSyncQuantified(row) {
    const _ids = row?.id ?? ids.value.join(',');
    modal
      .confirm('是否确认同步场景编号为"' + _ids + '"的异步量化场景下知识库？')
      .then(() => {
        return syncQuantify({ id: _ids });
      })
      .then(() => {
        getList();
        modal.msgSuccess('同步成功');
      })
      .catch(() => {});
  }

  function handleExport() {
    exportSdkLmScene(pageParams.value, queryParams.value);
  }

  function handleImport() {
    upload.value.title = '场景导入';
    upload.value.open = true;
  }

  function importTemplate() {
    tplSdkLmScene();
  }

  function handleFileUploadProgress() {
    upload.value.isUploading = true;
  }

  function handleFileSuccess(res, file) {
    upload.value.open = false;
    upload.value.isUploading = false;
    uploadRef.value.handleRemove(file);
    modal.msgSuccess(res.msg);
    getList();
  }

  function submitFileForm() {
    uploadRef.value.submit();
  }

  getList();
</script>
